from ctypes import (
    c_int, c_short, c_ushort,
    POINTER as _POINTER,
    byref as _byref,
    CDLL as _cdll
)
from os import strerror as _strerror
from settings import settings

if not settings.DEBUG:
    def _check_negative(result, func, arguments):
        if result >= 0:
            return result
        raise Exception(-result, _strerror(-result))


    _lib = _cdll("libSFP_interface_1_1.so", use_errno=True, use_last_error=True)

    _SFP1_Init = _lib.SFP1_Init
    _SFP1_Init.restype = c_int
    _SFP1_Init.errcheck = _check_negative

    _SFP1_rd_RX_Power_dBm = _lib.SFP1_rd_RX_Power_dBm
    _SFP1_rd_RX_Power_dBm.argtypes = (_POINTER(c_short),)
    _SFP1_rd_RX_Power_dBm.restype = c_int
    _SFP1_rd_RX_Power_dBm.errcheck = _check_negative

    _SFP1_rd_TX_Power_uWatt = _lib.SFP1_rd_TX_Power_uWatt
    _SFP1_rd_TX_Power_uWatt.argtypes = (_POINTER(c_ushort),)
    _SFP1_rd_TX_Power_uWatt.restype = c_int
    _SFP1_rd_TX_Power_uWatt.errcheck = _check_negative

    _SFP1_DeInit = _lib.SFP1_DeInit
    _SFP1_DeInit.restype = c_int
    _SFP1_DeInit.errcheck = _check_negative

    _SFP2_Init = _lib.SFP2_Init
    _SFP2_Init.restype = c_int
    _SFP2_Init.errcheck = _check_negative

    _SFP2_rd_RX_Power_dBm = _lib.SFP2_rd_RX_Power_dBm
    _SFP2_rd_RX_Power_dBm.argtypes = (_POINTER(c_short),)
    _SFP2_rd_RX_Power_dBm.restype = c_int
    _SFP2_rd_RX_Power_dBm.errcheck = _check_negative

    _SFP2_rd_TX_Power_uWatt = _lib.SFP2_rd_TX_Power_uWatt
    _SFP2_rd_TX_Power_uWatt.argtypes = (_POINTER(c_ushort),)
    _SFP2_rd_TX_Power_uWatt.restype = c_int
    _SFP2_rd_TX_Power_uWatt.errcheck = _check_negative

    _SFP2_DeInit = _lib.SFP2_DeInit
    _SFP2_DeInit.restype = c_int
    _SFP2_DeInit.errcheck = _check_negative


    def sfp_init(index: int):
        match index:
            case 0:
                _SFP1_Init()
            case 1:
                _SFP2_Init()


    def sfp_read_rx_power_dbm(index: int):
        rx_power = c_short(0)
        match index:
            case 0:
                _SFP1_rd_RX_Power_dBm(_byref(rx_power))
            case 1:
                _SFP2_rd_RX_Power_dBm(_byref(rx_power))

        return rx_power.value


    def sfp_read_tx_power_watt(index: int):
        tx_power = c_ushort(0)
        match index:
            case 0:
                _SFP1_rd_TX_Power_uWatt(_byref(tx_power))
            case 1:
                _SFP2_rd_TX_Power_uWatt(_byref(tx_power))

        return tx_power.value


    def sfp_deinit(index: int):
        match index:
            case 0:
                _SFP1_DeInit()
            case 1:
                _SFP2_DeInit()

else:
    def sfp_init(index: int):
        pass

    def sfp_read_rx_power_dbm(index: int) -> int:
        return 0


    def sfp_read_tx_power_watt(index: int) -> int:
       return 0


    def sfp_deinit(index: int):
        pass
